"""
Case Type   : 共享存储-系统内部工具-dsscmd
Case Name   : dsscmd工具删除卷组文件
Create At   : 2023/4/14
Owner       : opentestcase019
Description :
    1.删除卷组文件，指定-p path参数为正常值
    2.删除卷组文件，指定-p path参数为不存在的文件名
    3.删除卷组文件，指定-p path参数为命名不规范的文件名
    4.删除卷组文件，指定-U UDS:socket_domain参数为正常值
    5.删除卷组文件，指定错误的-U UDS:socket_domain参数
    6.删除卷组文件，指定权限不足的socket_domain
    7.在备机执行删除卷组文件
    8.在集群停止的情况下执行
    9.在dss关闭的情况下执行
Expect      :
    1.删除成功
    2.合理报错
    3.合理报错
    4.删除成功
    5.合理报错Failed to get uds connection.
    6.合理报错Failed to get uds connection.
    7.删除成功
    8.合理报错
    9.合理报错
History     :
"""
import os
import time
import unittest
from yat.test import Node
from yat.test import macro
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant

Primary_SH = CommonSH('PrimaryDbUser')


@unittest.skipIf(1 == Primary_SH.get_node_num(), '单机环境不执行')
class ShareStorageTool(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        self.logger.info(f"-----{os.path.basename(__file__)} start-----")
        self.primary_node = Node('PrimaryDbUser')
        self.standby_node = Node('Standby1DbUser')
        self.common = Common()
        self.constant = Constant()
        self.file_name = "file_dsscmd_0023"
        self.file_name_64chars = \
            "file_dsscmd_0023_file_dsscmd_0023_file_dsscmd_0023_file__64chars"
        self.logger.info("-----获取卷组名-----")
        execute_cmd = f"source {macro.DB_ENV_PATH};dsscmd lsvg"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn("Succeed to display lsvg info.", execute_msg, "获取卷组名失败")
        self.vgname = execute_msg.splitlines()[1].split()[0].strip()
        self.logger.info(self.vgname)
        self.file_path = os.path.join(self.vgname, self.file_name)
        self.file_path_64chars = os.path.join(self.vgname,
                                              self.file_name_64chars)

    def test_sharestorage_tool(self):
        step1 = "-----step1:删除卷组文件，指定-p path参数为正常值;expect:删除成功-----"
        self.logger.info(step1)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd touch -p +{self.file_path};" \
            f"dsscmd rm -p +{self.file_path}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"Succeed to create file, name is +{self.file_path}.",
                      execute_msg, "执行失败" + step1)
        self.assertIn(f"Succeed to remove device +{self.file_path}.",
                      execute_msg, "执行失败" + step1)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd ls -p +{self.vgname}"
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertNotIn(self.file_name, execute_msg, "执行失败" + step1)

        step2 = "-----step2:删除卷组文件，指定-p path参数为不存在的文件名;" \
                "expect:合理报错-----"
        self.logger.info(step2)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd rm -p +{self.file_path}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"The file {self.file_name} of +{self.file_path} "
                      f"does not exist", execute_msg, "执行失败" + step2)

        step3 = "-----step3:删除卷组文件，指定-p path参数为命名不规范的文件名;" \
                "expect:合理报错-----"
        self.logger.info(step3)
        cmd_list = [f'+{self.file_path}%#@', f'+{self.file_path_64chars}',
                    f'+{self.file_path}文件', f'{self.file_path}']
        for cmd in cmd_list:
            execute_cmd = f"source {macro.DB_ENV_PATH};dsscmd rm -p {cmd}"
            self.logger.info(execute_cmd)
            execute_msg = self.common.get_sh_result(self.primary_node,
                                                    execute_cmd)
            if cmd == cmd_list[1]:
                self.assertIn("Path  decode error name length should less "
                              "than 64", execute_msg, "执行失败" + step3)
            elif cmd == cmd_list[-1]:
                self.assertIn(f"cmd rm error:2193 Path {cmd} decode error , "
                              f"path should start with +.",
                              execute_msg, "执行失败" + step1)
            else:
                self.assertIn(f"decode error , path should be "
                              f"[0~9,a~z,A~Z,-,_,/,.]",
                              execute_msg, "执行失败" + step1)

        step4 = "-----step4:删除卷组文件，指定-U UDS:socket_domain参数为正常值;" \
                "expect:删除成功-----"
        self.logger.info(step4)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd touch -p +{self.file_path};" \
            f"dsscmd rm -p +{self.file_path} -U {macro.UDS_PATH}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"Succeed to create file, name is +{self.file_path}.",
                      execute_msg, "执行失败" + step4)
        self.assertIn(f"Succeed to remove device +{self.file_path}.",
                      execute_msg, "执行失败" + step4)

        step5 = "-----step5:删除卷组文件，指定错误的-U UDS:socket_domain参数;" \
                "expect:合理报错Failed to get uds connection.-----"
        self.logger.info(step5)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd touch -p +{self.file_path};" \
            f"dsscmd rm -p +{self.file_path} -U {macro.UDS_PATH}.cfg"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step5)

        step6 = "-----step6:删除卷组文件，指定权限不足的socket_domain;" \
                "expect:合理报错Failed to get uds connection.-----"
        self.logger.info(step6)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"chmod 000 {macro.UDS_PATH[4::]};" \
            f"dsscmd rm -p +{self.file_path} -U {macro.UDS_PATH};" \
            f"chmod 600 {macro.UDS_PATH[4::]}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step6)

        step7 = "-----step7:在备机执行删除卷组文件;expect:删除成功-----"
        self.logger.info(step7)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd rm -p +{self.file_path} -U {macro.UDS_PATH};"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"Succeed to remove device +{self.file_path}.",
                      execute_msg, "执行失败" + step7)

        step8 = "-----step8:在集群停止的情况下执行;expect:合理报错-----"
        self.logger.info(step8)
        stop_msg = Primary_SH.exec_cm_ctl(mode='stop')
        self.logger.info(stop_msg)
        self.assertIn(self.constant.cm_stop_success_msg,
                      stop_msg, '执行失败' + step8)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd rm -p +{self.file_path}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.standby_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step8)
        start_msg = Primary_SH.exec_cm_ctl(mode='start')
        self.logger.info(start_msg)
        self.assertIn(self.constant.cm_start_success_msg,
                      start_msg, '启动集群失败')
        time.sleep(30)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        self.assertIn('cluster_state   : Normal', status, "执行失败" + step8)

        step9 = "-----step9:在dss关闭的情况下执行;expect:合理报错-----"
        self.logger.info(step9)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd stopdss;" \
            f"sleep 2;" \
            f"dsscmd rm -p +{self.file_path}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step9)

    def tearDown(self):
        self.logger.info("-----恢复环境-----")
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        if "cluster_state   : Normal" not in status:
            start_msg = Primary_SH.exec_cm_ctl(mode='start')
            self.logger.info(start_msg)
        time.sleep(30)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        self.assertIn('cluster_state   : Normal', status, '恢复环境失败')
        self.logger.info(f"-----{os.path.basename(__file__)} end-----")
